package meatslope2.gameengine.gameobjects;

import meatslope2.constants.BitmapConstants;
import meatslope2.constants.SpriteConstants;
import meatslope2.constants.TimeConstants;
import meatslope2.gameengine.components.CollisionComponent;
import meatslope2.gameengine.components.Component;
import meatslope2.gameengine.engine.Engine.Time;
import meatslope2.gameengine.gameobjects.model.MovableGameObject;
import meatslope2.gameengine.primatives.HitInfo;

public class Player extends MovableGameObject implements IPlayerAction
{
	// ===========================================================
	// Constructors
	// ===========================================================
	private static final float JUMP_SPEED = 5f;
	private static final float RUN_SPEED = 1f;
	
	// ===========================================================
	// Members
	// ===========================================================
	
	private final CollisionComponent collisionComponent;
	private int playerState = PlayerState.IN_AIR;
	
	//The last time the player successfully jumped
	private float jumpTime = 0.0f;
	
	// ===========================================================
	// Constructors
	// ===========================================================
	
    public Player()
    {
    	super(SpriteConstants.PLAYER, BitmapConstants.PLAYER_WIDTH, BitmapConstants.PLAYER_HEIGHT);
    	
    	components = new Component[]{ collisionComponent = new CollisionComponent(this, CollisionComponent.FAT_MODE) };
    }
    
	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================
    
    @Override
    public void update()
    {
    	handleGroundTouch();

    	//gravity TODO: possibly make this in a physics component?
    	velocity.add(0, -9.8f * Time.getDeltaTime());
    	
    	super.update();
    }
    
	// ===========================================================
	// Methods
	// ===========================================================
    
    private void handleGroundTouch() 
    {
    	//We're touching the ground and have given the player a chance to gain some height
    	if(collisionComponent.getVerticalHit().isHit() && !startedJumping())
    	{
    		final HitInfo verticalHit = collisionComponent.getVerticalHit();
    		
    		//If our velocityY is dropping, then what we hit was ground
    		if(verticalHit.getHitNormal().y > 0)
    		{
    			velocity.y = 0;
    			playerState = PlayerState.TOUCHING_GROUND;
    		}
    	}
	}

	public void jump()
    {
    	if(playerState == PlayerState.TOUCHING_GROUND)
    	{
    		velocity.add(0, JUMP_SPEED);
    		playerState = PlayerState.IN_AIR;
    		jumpTime = Time.getTotalTime();
    	}
    }
    
    /**
     * @return if the player jumped recently
     */
    private boolean startedJumping()
    {
    	return Time.getTotalTime() < jumpTime + TimeConstants.COLLISION_SURFACE_DECAY_TIME;
    }

	public void runLeft() 
	{
		velocity.x = -RUN_SPEED;
	}
	
	public void runRight()
	{
		velocity.x = RUN_SPEED;
	}

	public void stop() 
	{
		velocity.x = 0;
	}
}
